package logic

import (
	"context"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
	"gozerogateway/rpc/model/svcmodel"

	"encoding/json"
	"errors"
	"github.com/zeromicro/go-zero/core/logx"
	"gozerogateway/rpc/svc/internal/svc"
	"gozerogateway/rpc/svc/svcclient"
)

type ServiceUpdateGrpcLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewServiceUpdateGrpcLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ServiceUpdateGrpcLogic {
	return &ServiceUpdateGrpcLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *ServiceUpdateGrpcLogic) ServiceUpdateGrpc(in *svcclient.ServiceUpdateGrpcReq) (*svcclient.ServiceUpdateGrpcResp, error) {
	// todo: add your logic here and delete this line

	serviceinfo, err := l.svcCtx.SvcModel.FindOneByServiceNameAntReturn(l.ctx, in.ServiceName)
	if err != nil {
		reqStr, _ := json.Marshal(in)
		logx.WithContext(l.ctx).Errorf("(grpc) 根据service_name查询info表信息失败,this http service is not exist,参数:%s,异常:%s", reqStr, err.Error())
		return nil, err
	}
	ServiceId := serviceinfo.Id
	_, err = l.svcCtx.SvcAccessControlModel.FindOne(l.ctx, ServiceId)
	if err != nil {
		reqStr, _ := json.Marshal(in)
		logx.WithContext(l.ctx).Errorf("根据service_id查询accesscontrol表信息失败,参数:%s,异常:%s", reqStr, err.Error())
		return nil, err
	}

	_, err = l.svcCtx.SvcLoadBalanceModel.FindOne(l.ctx, ServiceId)
	if err != nil {
		reqStr, _ := json.Marshal(in)
		logx.WithContext(l.ctx).Errorf("根据service_id查询loadbalance表信息失败,参数:%s,异常:%s", reqStr, err.Error())
		return nil, err
	}

	if errtrans := l.svcCtx.SvcHttpModel.TransCtx(l.ctx, func(ctx context.Context, session sqlx.Session) error {
		_, err = l.svcCtx.SvcHttpModel.FindOne(l.ctx, ServiceId)

		if errUpdateGrpcTable0 := l.svcCtx.SvcModel.TransUpdate(l.ctx, session, &svcmodel.GatewayServiceInfo{
			ServiceName: in.ServiceName, //not update, use servicename to find
			ServiceDesc: in.ServiceDesc,
		}); errUpdateGrpcTable0 != nil {
			return errUpdateGrpcTable0
		}

		if errUpdateGrpcTable1 := l.svcCtx.SvcLoadBalanceModel.TransUpdate(l.ctx, session, &svcmodel.GatewayServiceLoadBalance{
			ServiceId:  ServiceId,
			RoundType:  in.RoundType,
			IpList:     in.IpList,
			WeightList: in.WeightList,
			ForbidList: in.ForbidList,
		}); errUpdateGrpcTable1 != nil {
			return errUpdateGrpcTable1
		}
		if errUpdateGrpcTable0 := l.svcCtx.SvcGrpcModel.TransUpdate(l.ctx, session, &svcmodel.GatewayServiceGrpcRule{
			ServiceId: ServiceId,
			Port:      in.Port,
		}); errUpdateGrpcTable0 != nil {
			return errUpdateGrpcTable0
		}
		if errUpdateGrpcTable2 := l.svcCtx.SvcAccessControlModel.TransUpdate(l.ctx, session, &svcmodel.GatewayServiceAccessControl{
			ServiceId:         ServiceId,
			OpenAuth:          in.OpenAuth,
			BlackList:         in.BlackList,
			WhiteList:         in.WhiteList,
			WhiteHostName:     in.WhiteHostName,
			ClientipFlowLimit: in.ClientIPFlowLimit,
			ServiceFlowLimit:  in.ServiceFlowLimit,
		}); errUpdateGrpcTable2 != nil {
			return errUpdateGrpcTable2
		}

		return nil
	}); errtrans != nil {
		return nil, errors.New("trans update grpc table error")
	}

	return &svcclient.ServiceUpdateGrpcResp{
		Isok: 1,
	}, nil
}
